package com.joe.lucene.analyzer;

import java.io.IOException;
import java.io.Reader;
import org.apache.lucene.analysis.Token;
import org.apache.lucene.analysis.Tokenizer;

public final class MarcTokenizer extends Tokenizer {
	private int offset = 0;
	private int bufferIndex = 0;
	private int dataLen = 0;
	private static final int MAX_WORD_LEN = 255;
	private static final int IO_BUFFER_SIZE = 1024;
	private final char[] buffer = new char[255];
	private final char[] ioBuffer = new char[1024];
	private int length;
	private int start;

	public MarcTokenizer(Reader reader) {
		input = reader;
	}

	private final void push(char c) {
		if (length == 0)
			start = offset - 1;
		buffer[length++] = Character.toLowerCase(c);
	}

	private final Token flush() {
		if (length > 0)
			return new Token(new String(buffer, 0, length), start, start
					+ length);
		return null;
	}

	public final Token next() throws IOException {
		length = 0;
		start = offset;
		for (;;) {
			offset++;
			if (bufferIndex >= dataLen) {
				dataLen = input.read(ioBuffer);
				bufferIndex = 0;
			}
			if (dataLen == -1)
				return flush();
			char c = ioBuffer[bufferIndex++];
			switch (Character.getType(c)) {
			case 1:
			case 2:
			case 9:
				push(c);
				if (length == 255)
					return flush();
				break;
			case 5:
				if (length > 0) {
					bufferIndex--;
					return flush();
				}
				push(c);
				return flush();
			default:
				if (c == '-' || c == '.' || c == ':' || c == '/') {
					push(c);
					if (length == 255)
						return flush();
				} else if (length > 0)
					return flush();
			}
		}
	}

	private final boolean isDigit(char c) {
		if (Character.getType(c) == 9)
			return true;
		return false;
	}
}